#pragma once

#include <iostream>
#include <string>
#include <vector>
#include <map>

#include "PKB.h"
#include "ParserCallHelper.h"
//#include "ParserProcGraphHelper.h"

using namespace std;

class Parser {
	private:
		PKB* mPKB;
		//ParserProcGraphHelper graph;
		string procName;//name of current procedure
		string currProc;//source code string of current procedure
		string varName;
		//layer# to indicate container stmt
		size_t layerCounter;
		static const char LEFT_BRACE = '{';
		static const char RIGHT_BRACE = '}';
		string remainSrc;
		int pos;
		int totalProc;
		vector<string> validProc;
		vector<string> calledProc;
		vector<string> procNames;
		vector<ParserCallHelper> callHelperTable;

		// Debugging
		int isStmtCounter;
		int isStmtLstCounter;
		
		bool isProgram(string src);
		TreeNode* isProcedure(string);
		TreeNode* isStmtLst(string, bool, int, int *lastLineOfStmtLst);//isStmtLst(src,isParent,parentStmtNum) 0 if not parent
		TreeNode* isStmt(string, int *lastLineOfContainer);
		TreeNode* isCall(string);
		TreeNode* isAssign(string);
		TreeNode* isWhile(string, int *lastLineOfContainer);
		TreeNode* isIf(string src, int *lastLineOfContainer);

		int matchBraces(string);
		bool isName(string);
		bool isNum(string);
		bool isLetter(char);
		bool isDigit(char);
		bool match(string, string);
		bool matchCaseInsensitive(string, string);
		bool isCallValid(vector<string>,vector<string>);
		std::string trim(const std::string&);
		std::string toLowerCaseString(std::string);
		std::string removeCommentsFromSrc(std::string src);
		/// Given a string, extracts the first name or number which it encounters from the string and returns it (thereby removing it)
		std::string extractFirstNameOrNumber(std::string *str);
		/*!
		 Takes a mathematical expression like (x+2*(y+x)) and inserts the variables and constants into the PKB member variable,
			and finally returns the set of used variables.
		  NOTE: Does NOT check if the expr is valid. The expr should be validated by using QueryExpressionParser after calling this function.
		*/
		std::vector<std::string> insertVariablesAndConstantsIntoPKB(std::string expr);
		/// Same as standard stoi, except that an integer "00123" is understood as 123!
		int mystoi(std::string s);
	public:
		//stmt#
		size_t stmtCounter;
		size_t progLineCounter;
		Parser(PKB*);

		//map <stmt#, layer#>
		map <size_t,size_t>  stmtTable;

		bool executeSrc(string src);
	
};

